﻿using System;
using System.Collections;
using System.Collections.Generic;
using SConsole = System.Console;

namespace Hydrogen.Console
{
    /// <summary>
    /// 控制台日志
    /// </summary>
    public static class ConsoleLog
    {
        private static object lockObj = new object();
        public static ConsoleColor NormalColor = ConsoleColor.White;
        public static ConsoleColor ErrorColor = ConsoleColor.Red;
        public static ConsoleColor WarningColor = ConsoleColor.Yellow;

        /// <summary>
        /// 打一行日志
        /// </summary>
        /// <param name="log"></param>
        /// <param name="args"></param>
        public static void Log(string log, params object[] args)
        {
            WriteColor("[*NORMALLOG*]\t", NormalColor);
            WriteColorLine(log, NormalColor, args);
        }
        /// <summary>
        /// 打印文字，不换行
        /// </summary>
        /// <param name="log"></param>
        /// <param name="args"></param>
        public static void Write(string log, params object[] args)
        {
            WriteColor(log, NormalColor, args);
        }
        /// <summary>
        /// 错误日志
        /// </summary>
        /// <param name="log"></param>
        /// <param name="args"></param>
        public static void LogError(string log, params object[] args)
        {
            WriteColor("[*ERROR*]\t", ErrorColor);
            WriteColorLine(log, ErrorColor, args);
        }
        /// <summary>
        /// 经过日志
        /// </summary>
        /// <param name="log"></param>
        /// <param name="args"></param>
        public static void LogWarning(string log, params object[] args)
        {
            WriteColor("[*WARNING*]\t", WarningColor);
            WriteColorLine(log, WarningColor, args);
        }
        /// <summary>
        /// 打印带颜色的文字，换行
        /// </summary>
        /// <param name="log"></param>
        /// <param name="color"></param>
        public static void WriteColorLine(string log, ConsoleColor color, params object[] args)
        {
            lock (lockObj)
            {
                var temp = SConsole.ForegroundColor;
                SConsole.ForegroundColor = color;
                SConsole.WriteLine(log, args);
                SConsole.ForegroundColor = temp;
            }
        }
        /// <summary>
        /// 打印带颜色文字，不换行
        /// </summary>
        /// <param name="log"></param>
        /// <param name="color"></param>
        public static void WriteColor(string log, ConsoleColor color, params object[] args)
        {
            lock (lockObj)
            {
                var temp = SConsole.ForegroundColor;
                SConsole.ForegroundColor = color;
                SConsole.Write(log, args);
                SConsole.ForegroundColor = temp;
            }
        }

        public static void WriteTreeLevel(string content, ConsoleColor color, int deep, bool isEnd, params object[] args)
        {
            for (int i = 0; i < deep; i++)
            {
                SConsole.Write("│\t");
            }
            SConsole.Write(isEnd ? "┗" : "┣");
            SConsole.Write("  ");
            WriteColorLine(content, color, args);
        }

        public static void Write(IEnumerable<ConsoleTreeNode> tree)
        {
            List<int> levelList = new List<int>();
            foreach (var item in tree)
            {
                if (levelList.Count < item.level + 1)
                {
                    int currentCount = levelList.Count;
                    for (int i = 0; i < item.level + 1 - currentCount; i++)
                    {
                        levelList.Add(0);
                    }
                }

                levelList[item.level]++;
            }
            List<ConsoleTreeNode> list = new List<ConsoleTreeNode>(tree);
            for (int i = 0; i < list.Count; i++)
            {
                for (int k = 0; k < list[i].level; k++)
                {
                    if (levelList[k] > 0) SConsole.Write("│\t");
                    else SConsole.Write("\t");
                }
                levelList[list[i].level]--;
                bool isend = levelList[list[i].level] <= 0 || (i + 1 < list.Count && list[i + 1].level < list[i].level);
                if (list[i].level > 0) SConsole.Write(isend ? "┗" : "┣");
                SConsole.Write("  ");
                if (list[i].onDraw != null)
                {
                    try
                    {
                        list[i].onDraw.Invoke();
                    }
                    catch (Exception e)
                    {
                        LogError(e.ToString());
                    }
                }
            }

        }
    }

    public class ConsoleTreeNode
    {
        public int level;
        public Action onDraw;
    }
}
